<?php

namespace App\Http\Controllers;

use App\Models\MiniUser;
use App\Models\UserRole;
use App\Models\Users;

use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;


class UsersController extends BaseController
{
    /**
     * Display a listing of the resource.
     *
     * @param  Request  $request
     * @return JsonResponse
     */
    public function index(Request $request): JsonResponse
    {
        //
        $name = $request->get("user_name");
        $phone = $request->get("phone");
        $pageNum = $request->get("page_num");
        $pageSize = $request->get("page_size", 10);
        $type = $request->get("type");
        $where = [['status',1]];

        if($type=="system"){
            $user = Users::where($where)
                ->where(function ($query) use ($name) {
                    return $query->when($name, function ($query) use ($name) {
                        $name = str_replace(" ", "", strtolower($name));
                        return $query->where('nickname', "like", "%".$name."%")->orWhere('name_py_f', "like",
                            "%".$name."%")->orWhere('name_py_s', "like", "%".$name."%");
                    });

                })
                ->where(function ($query) use ($phone) {
                    return $query->when($phone, function ($query) use ($phone) {
                        $phone = str_replace(" ", "", strtolower($phone));
                        return $query->where('phone', "like", "%".$phone."%");
                    });
                })
                ->with(
                    [
                        "roles" => function ($query) {
                            return $query->where("role.status", 1)->select("role.id as role_id", "role.name as role_name");
                        },
                    ])
                ->orderBy("updated_at","desc")
                ->select("id", "name", "nickname", "phone", "email", "avator", "department_id", "last_login_at",
                    "last_login_ip", "status", "is_locked", "is_admin", "is_supper_admin", "updated_at", "created_at")
                ->paginate($pageSize, ['*'], "page", $pageNum);
        }else{
            $user = MiniUser::where($where)
                ->where(function ($query) use ($name) {
                    return $query->when($name, function ($query) use ($name) {
                        $name = str_replace(" ", "", strtolower($name));
                        return $query->where('nickname', "like", "%".$name."%")->orWhere('name_py_f', "like",
                            "%".$name."%")->orWhere('name_py_s', "like", "%".$name."%");
                    });

                })
                ->where(function ($query) use ($phone) {
                    return $query->when($phone, function ($query) use ($phone) {
                        $phone = str_replace(" ", "", strtolower($phone));
                        return $query->where('phone', "like", "%".$phone."%");
                    });
                })
                ->orderBy("updated_at","desc")
                ->select("id", "name", "nickname", "phone", "openid", "avator", "last_login_at",
                    "last_login_ip", "status", "is_locked", "updated_at", "created_at")
                ->paginate($pageSize, ['*'], "page", $pageNum);
        }

        $list = $user->getCollection();
        return Success(10100, [
            "data" => $list, "page_info" => [
                'current' => $user->currentPage(), 'page_size' => (int) $pageSize, "count" => $user->total(),
                "pages" => $user->lastPage()
            ]
        ]);

    }


    /**
     * Store a newly created resource in storage.
     *
     * @param  Request  $request
     * @return JsonResponse
     */
    public function store(Request $request): JsonResponse
    {
        //

        $password = $request->get("password");
        $nickname = $request->get("nickname");

        $phone = $request->get("phone");

        $is_supper_admin = $request->get("is_supper_admin",0);



        $roles_id = $request->get("roles");

        if (!$password || !$nickname || !$phone || !$roles_id) {
            return Failed(10002, [
                "file" => "UsersController", "line" => __LINE__,
                "need_filed" => [ 'password', 'nickname', 'phone', 'roles_id',]
            ]);
        }
        $name_py_f = getFullPinYin($nickname);
        $name_py_s = getShortpinyin($nickname);

        $file = $request->file('avator');
        $destinationPath = 'image/avators/';
        if (!$file) {
            $file_path_name = $name_py_f."_avator.png";
            copy(public_path().'/image/avator/'.rand(1, 5).".png", $destinationPath.$file_path_name);
        } else {
            $file_path_name = $name_py_f."_avator.".$file->getClientOriginalExtension();

            try {
                $res = $file->move($destinationPath, $file_path_name);
                if (!$res) {
                    return Failed(10002,
                        ["file" => "UsersController", "line" => __LINE__, "FileUploadFiled" => $file_path_name]);
                }
            } catch (\Exception $exception) {
                return Failed(10002,
                    ["file" => "UsersController", "line" => __LINE__, "FileUploadFiled" => $exception->getMessage()]);
            }
        }

        $user = Users::where([ ["nickname",$nickname],['password', md5($password)], ["phone", $phone]])->first();
        if ($user) {
            if ($user->status == 1) {
                return Failed(10006, ["file" => "UsersController", "line" => __LINE__, "user_exits" => $nickname]);
            }
            return Failed(40005, ["file" => "UsersController", "line" => __LINE__, "user_exits" => $nickname]);
        }
        $data = [
            'name' => $nickname,
            'password' => md5($password),
            'nickname' => $nickname,
            'name_py_f' => $name_py_f,
            'name_py_s' => $name_py_s,
            'email' => '',
            'phone' => $phone,
            'status' => 1,
            'avator' => $destinationPath.$file_path_name,
            'is_supper_admin' => $is_supper_admin,
            'is_admin' => $is_supper_admin,
            'updated_at' => date("Y-m-d H:i:s"),
            'created_at' => date("Y-m-d H:i:s"),
        ];
        $user = Users::create($data);
        if (!$user) {
            return Failed(10001, ["file" => "UsersController", "line" => __LINE__, "user_exits" => $nickname]);
        }
        foreach ($roles_id as $vo) {
            UserRole::create([
                "user_id" => $user->id,
                "role_id" => $vo,
                "created_at" => date("Y-m-d H:i:s"),
                "updated_at" => date("Y-m-d H:i:s")
            ]);
        }
        return Success(10000, []);
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return JsonResponse|\Illuminate\Http\Response
     */
    public function show(int $id): JsonResponse
    {
        //
        if (!$id) {
            return Failed(10002, ["file" => "UsersController", "line" => __LINE__, "need_filed" => ['id']]);
        }
        $user = Users::where([["id", $id]])->first();
        $permission =  $this->getUserPermissionAndMenu();

        if (!$user) {
            return Failed(11101, ["file" => "UsersController", "line" => __LINE__, "resources" => "not_found"]);
        }
        return Success(11100, ["data" => $user,"permission"=>array_values($permission['permission']),"menu"=>array_values($permission['menu'])]);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function update(Request $request, int $id): \Illuminate\Http\JsonResponse
    {
        //
        if (!$id) {
            return Failed(10002, ["file" => "UsersController", "line" => __LINE__, "need_filed" => ['id']]);
        }

        $user = Users::where([["id", $id], ['status', 1]])->first();

        if (!$user) {
            return Failed(10005, ["file" => "UsersController", "line" => __LINE__, "resources" => "not_found"]);
        }


        $password = $request->get("password");
        $nickname = $request->get("nickname");

        $phone = $request->get("phone");

        $is_supper_admin = $request->get("is_supper_admin");
        $is_admin = $request->get("is_admin");

        $is_locked = $request->get("is_locked");
        $depart_leader = $request->get("depart_leader");
        $data = [];

        if ($password) {
            $data['password'] = md5($password);
        }
        if ($nickname) {
            $name_py_f = getFullPinYin($nickname);
            $name_py_s = getShortpinyin($nickname);
            $data['nickname'] = $nickname;
            $data['name_py_f'] = $name_py_f;
            $data['name_py_s'] = $name_py_s;
        }

        if ($phone) {
            $data['phone'] = $phone;
        }


        if ($is_locked && $is_locked != $user->is_locked) {
            $data['is_locked'] = $is_locked;
        }

        if ($is_supper_admin && $is_supper_admin != $user->is_supper_admin) {
            $data['is_supper_admin'] = $is_supper_admin;
        }

        if ($depart_leader && $depart_leader != $user->depart_leader) {
            $data['depart_leader'] = $depart_leader;
        }

        if ($is_admin && $is_admin != $user->is_admin) {
            $data['is_admin'] = $is_admin;
        }
        $data ['updated_at'] = date("Y-m-d H:i:s");

        if (!Users::where("id", $id)->update($data)) {
            return Failed(11010, ["file" => "UsersController", "line" => __LINE__, "resources" => "updated_error"]);
        }
        $roles_id = $request->get("roles");
        UserRole::where("user_id", $id)->delete();
        foreach ($roles_id as $vo) {
            UserRole::create([
                "user_id" => $user->id,
                "role_id" => $vo,
                "created_at" => date("Y-m-d H:i:s"),
                "updated_at" => date("Y-m-d H:i:s")
            ]);
        }
        return Success(11000, ["file" => "UsersController", "line" => __LINE__, "resources" => "updated_success"]);

    }

    public function updateWithFile(Request $request): \Illuminate\Http\JsonResponse
    {
        //
        $id = $request->get("id");
        $name = $request->input("name");
        $password = $request->get("password");
        $nickname = $request->get("nickname");
        $email = $request->get("email");
        $phone = $request->get("phone");
        $department_id = $request->get("department_id");
        $is_supper_admin = $request->get("is_supper_admin");
        $is_admin = $request->get("is_admin");
        $name_py_f = getFullPinYin($nickname);
        $name_py_s = getShortpinyin($nickname);
        $status = $request->get("status", 1);
        $is_locked = $request->get("is_locked");
        $file = $request->file('avator');

        if (!$id) {
            return Failed(10002, ["file" => "UsersController", "line" => __LINE__, "need_filed" => ['id']]);
        }
        $user = Users::where([["id", $id], ['status', 1]])->first();
        if (!$user) {
            return Failed(10005, ["file" => "UsersController", "line" => __LINE__, "resources" => "not_found"]);
        }
        $destinationPath = 'image/avators/';
        if (!$file) {
            $file_path_name = 'image/avators/'.$name_py_f."_avator.png";
            copy(public_path().$destinationPath.rand(1, 5).".png", $file_path_name);
        } else {
            $file_path_name = $name_py_f."_avator.".$file->getClientOriginalExtension();

            try {
                $res = $file->move($destinationPath, $file_path_name);
                if (!$res) {
                    return Failed(10002,
                        ["file" => "UsersController", "line" => __LINE__, "FileUploadFiled" => $file_path_name]);
                }
            } catch (\Exception $exception) {
                return Failed(10002,
                    ["file" => "UsersController", "line" => __LINE__, "FileUploadFiled" => $exception->getMessage()]);
            }
        }

        $data = [
            'name' => $name,
            'password' => md5($password),
            'nickname' => $nickname,
            'name_py_f' => $name_py_f,
            'name_py_s' => $name_py_s,
            'email' => $email,
            'phone' => $phone,
            'avator' => $destinationPath.$file_path_name,
            'status' => $status,
            'department_id' => $department_id,
            'is_supper_admin' => $is_supper_admin,
            'is_locked' => $is_locked,
            'is_admin' => $is_admin,
            'updated_at' => date("Y-m-d H:i:s"),
        ];

        if (!Users::where("id", $id)->update($data)) {
            return Failed(11010, ["file" => "UsersController", "line" => __LINE__, "resources" => "updated_error"]);
        }

        if ($is_locked == 0) {
            if ($user->token != "") {
                \JWTAuth::setToken($user->token)->invalidate();
            }
        }
        return Success(11000, ["file" => "UsersController", "line" => __LINE__, "resources" => "updated_success"]);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function destroy(int $id): \Illuminate\Http\JsonResponse
    {
        //
        if (!$id) {
            return Failed(10002, ["file" => "UsersController", "line" => __LINE__, "need_filed" => ['id']]);
        }
        $user = Users::where([["id", $id], ['status', 1]])->first();
        if (!$user) {
            return Failed(10005, ["file" => "UsersController", "line" => __LINE__, "resources" => "not_found"]);
        }
        $user->status = 0;
        $user->updated_at = date("Y-m-d H:i:s");
        if (!$user->save()) {
            return Failed(10007, ["file" => "UsersController", "line" => __LINE__, "resources" => "delete_failed"]);
        }
        return Success(10700, ["file" => "UsersController", "line" => __LINE__, "resources" => "delete_success"]);
    }


    /**
     * Get the token array structure.
     *
     * @param  string  $token
     *
     * @return JsonResponse
     */
    public function bindRole(Request $request, int $user_id): JsonResponse
    {

        $roleArr = $request->get("roleArr");

        if (!$user_id || empty($roleArr)) {
            return Failed(10002,
                ["file" => "UsersController", "line" => __LINE__, "need_filed" => ['user_id', 'roleArr']]);
        }
        $data = [];
        foreach ($roleArr as $key => $vo) {
            $data[$key] = [
                "user_id" => $user_id,
                "role_id" => $vo,
                "updated_at" => date("Y-m-d H:i:s"),
                "created_at" => date("Y-m-d H:i:s"),
            ];
        }
        try {
            if (!UserRole::insert($data)) {
                return Failed(10001, ['file' => "UsersController", "line" => __LINE__, "msg" => "用户绑定角色失败"]);
            }
        } catch (\Illuminate\Database\QueryException $ex) {
            return Failed(10006, ['file' => "UsersController", "line" => __LINE__, "same" => $data]);
        }
        return Success(10000, []);
    }

    public function updatePassword(Request $request, $user_id)
    {
        $old_password = $request->get("old_password");
        $new_password = $request->get("new_password");
        $confirm_password = $request->get("confirm_password");
        if (!$user_id || !$old_password || !$new_password || !$confirm_password) {
            return Failed(10002, [
                "file" => "UsersController", "line" => __LINE__,
                "need_filed" => ['user_id', 'old_password', 'new_password', 'confirm_password']
            ]);
        }
        if ($new_password != $confirm_password) {
            return Failed(10301, [
                "file" => "UsersController", "line" => __LINE__, "ErrorFiled" => ['new_password', 'confirm_password']
            ]);
        }
        $user = Users::where("id", $user_id)->first();
        if (!$user) {
            return Failed(10005, ["file" => "UsersController", "line" => __LINE__, "resources" => "not_found"]);
        }
        if ($user->status == 0) {
            return Failed(40005, ["file" => "UsersController", "line" => __LINE__, "resources" => "not_found"]);
        }
        if ($user->is_locked == 1) {
            return Failed(40007, ["file" => "UsersController", "line" => __LINE__, "resources" => "not_found"]);
        }
        if ($user->password != md5($old_password)) {
            return Failed(40004, ["file" => "UsersController", "line" => __LINE__, "resources" => "not_found"]);
        }
        $user->password = md5($new_password);
        $user->updated_at = date("Y-m-d H:i:s");
        if (!$user->save()) {
            return Failed(11010, ["file" => "UsersController", "line" => __LINE__, "resources" => "updated_error"]);
        }

        if ($user->token != "") {
            \JWTAuth::setToken($user->token)->invalidate();
        }

        return Success(11000, ["file" => "UsersController", "line" => __LINE__, "resources" => "updated_success"]);
    }

}
